package com.hc.security;

import com.hc.domain.User;
import com.hc.service.UserService;
import com.hc.utils.JwtUtils;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtException;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.web.authentication.www.BasicAuthenticationFilter;

import javax.annotation.Resource;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * Jwt认证器：携带jwt信息的自动登录
 *
 * @author 梁云亮
 */

public class TokenAuthenticationFilter extends BasicAuthenticationFilter {

    @Resource
    private JwtUtils jwtUtils;

    @Resource
    private UserService userService;

    public TokenAuthenticationFilter(AuthenticationManager authenticationManager) {
        super(authenticationManager);
    }

    @Resource
    private MyUserDetailService myUserDetailService;  //引入MyUserDetailsService主要为了代码利用
    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {
        String token = request.getHeader(jwtUtils.getHeader());
        //如果jwt为null不需要自动登录
        if (token == null || token.length() == 0 || token.equals("null") || token.equals("undefined")) {
            chain.doFilter(request, response);
            return;
        }

        Claims claim = jwtUtils.getClaimByToken(token);
        if (claim == null) {
            throw new JwtException("token 异常");
        }
        if (jwtUtils.isTokenExpired(claim)) {
            throw new JwtException("token已过期");
        }

        //获取用户名
        String username = claim.getSubject();
        // 获取用户的权限等信息

        User user = userService.getUserByUsername(username);

        List<GrantedAuthority> authorityList = myUserDetailService.getGrantedAuthorities(user);
        UsernamePasswordAuthenticationToken auth = new UsernamePasswordAuthenticationToken(username, user.getPassword(), authorityList);

        //将用户信息交给SpringSecurity，以实现自动登录
        SecurityContextHolder.getContext().setAuthentication(auth);

        chain.doFilter(request, response);
    }
}
